package org.mozhu.mboot.core.web;

import com.google.common.collect.Maps;
import org.mozhu.mboot.core.json.JSON;

import java.util.Map;

public class AjaxResponse {
    private static final String OPERATION_FAIL = "operation fail";
    private static final String OPERATION_SUCCESS = "operation success";
    private static final String DEFAULT_ERROR_CODE = "-1";
    private Boolean success;
    private String message;
    private Object data;
    private String errorCode;

    public AjaxResponse() {
        this(Boolean.TRUE, defaultSuccessMessage());
    }

    public AjaxResponse(Boolean success) {
        this(success, success ? defaultSuccessMessage() : defaultFailMessage());
    }

    public AjaxResponse(String message) {
        this(Boolean.TRUE, message);
    }

    public AjaxResponse(Boolean success, String message) {
        this.success = success;
        this.message = message;
        if (Boolean.FALSE.equals(success)) {
            this.errorCode = DEFAULT_ERROR_CODE;
        }
    }

    public AjaxResponse(Boolean success, String message, Object data) {
        this(success, message);
        this.data = data;
    }

    public AjaxResponse(String errorCode, String message, Object data) {
        this(Boolean.FALSE, message, data);
        this.errorCode = errorCode;
    }

    private static String defaultSuccessMessage() {
        return OPERATION_SUCCESS;
    }

    private static String defaultFailMessage() {
        return OPERATION_FAIL;
    }

    public static AjaxResponse fail() {
        return fail(defaultFailMessage());
    }

    public static AjaxResponse fail(String message) {
        return new AjaxResponse(Boolean.FALSE, message);
    }

    public static AjaxResponse fail(String message, Object data) {
        return new AjaxResponse(Boolean.FALSE, message, data);
    }

    public static AjaxResponse fail(String errorCode, String message) {
        return new AjaxResponse(errorCode, message, null);
    }

    public static AjaxResponse fail(String errorCode, String message, Object data) {
        return new AjaxResponse(errorCode, message, data);
    }

    public static AjaxResponse success() {
        return success(null);
    }

    public static AjaxResponse success(String message) {
        return new AjaxResponse(Boolean.TRUE, message);
    }

    public static AjaxResponse success(String message, Object data) {
        return new AjaxResponse(Boolean.TRUE, message, data);
    }

    public static AjaxResponse successWithData(Object data) {
        return new AjaxResponse(Boolean.TRUE, null, data);
    }

    public Boolean getSuccess() {
        return success;
    }

    public void setSuccess(Boolean success) {
        this.success = success;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public String getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(String errorCode) {
        this.errorCode = errorCode;
    }

    public AjaxResponse extraData(String key, Object extraData) {
        Map<String, Object> dataAsMap = getDataAsMap();
        dataAsMap.put(key, extraData);
        this.data = dataAsMap;
        return this;
    }

    private Map<String, Object> getDataAsMap() {
        if (data == null) {
            return Maps.newHashMap();
        } else if (data instanceof Map) {
            return (Map<String, Object>) data;
        } else {
            return JSON.toMap(JSON.toJson(data), String.class, Object.class);
        }
    }
}
